package com.xt.base.util;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import net.sf.json.JSONException;

import org.apache.commons.lang.StringUtils;

import com.xt.base.reflection.UV.Tuple;

public class Tokenizer {


	private Reader reader;

	private int index = 0;

	private char[] symbols = new char[0];

	private char lastChar;

	private boolean useLastChar;

	public Tokenizer(String input, char[] symbols) {
		input = StringUtils.trim(input);
		this.reader = new StringReader(input);
		this.symbols = symbols;
		this.useLastChar = false;
	}

	private boolean isMatch(char in) {
		for (char c : symbols) {
			if (c == in)
				return true;
		}
		return false;
	}

	public void back() throws JSONException {
		if (!useLastChar && index > 0) {
			index -= 1;
			useLastChar = true;
		}
	}

	public boolean more() {
		char nextChar = next();
		if (nextChar == 0) {
			return false;
		}
		back();
		return true;
	}

	public char next() {
		if (this.useLastChar) {
			this.useLastChar = false;
			if (this.lastChar != 0) {
				this.index += 1;
			}
			return this.lastChar;
		}
		int c;
		try {
			c = this.reader.read();
		} catch (IOException exc) {
			throw new JSONException(exc);
		}

		if (c <= 0) {
			this.lastChar = 0;
			return 0;
		}
		this.index += 1;
		this.lastChar = (char) c;
		return this.lastChar;
	}

	public Tuple<String, Character> getToken() {
		StringBuilder builder = new StringBuilder();
		Character sym = null;
		while (more()) {
			char c = next();
			if (isMatch(c)) {
				sym = c;
				break;
			} else
				builder.append(c);
		}
		return new Tuple<String, Character>(builder.toString(), sym);
	}

	public List<Tuple<String, Character>> getTokens() {
		List<Tuple<String, Character>> res = new ArrayList<Tuple<String, Character>>();
		while (more())
			res.add(getToken());
		return res;
	}
}
